/*********************************
* Freamwork.h
*********************************/
#include <string>
#include <vector>
#include <iostream>
#include <mqueue.h>
#include <sys/types.h>

using namespace std;

#define FIX_KEY_PTB 0x6418f5ac
#define MAX_MSG_NUM 10
#define MAX_SIZE_MSG 512
#define PROCESS_LIST_FILE "/home/public/test/testIPC/src/initiallizeProcess.ini"

// all define of evnet id number
#define ID_StartAllProcess 100
#define ID_KillAllProcess 101

//class define
class TFW_Serializable;
class TFW_Stream;
class TFW_EventDispatcher;

/* Serializable */
class TFW_Serializable
{
public :
	virtual void serialize(TFW_Stream& buf) const = 0;
	virtual void deserialize(TFW_Stream& buf) = 0;
	virtual ~TFW_Serializable(){};
};

/********************************
* Process 
********************************/
class Process
{
private:
	string m_path;
	string m_name;
	int m_startTime;
	pid_t m_pid;
	//ProcessStatus m_status;

public :
	typedef enum
	{
		st_stopped,
		st_starting,
		st_running,
	}ProcessStatus;
	ProcessStatus m_status;

public :
	Process():m_status(st_stopped){};
	~Process(){};
public :
	void setPath(string varPath){m_path = varPath;}
	void setName(string varName){m_name = varName;}
	void setStartTime(int varTime){m_startTime = varTime;}
	string getPath(){return m_path;}
	string getName(){return  m_name;}
	int getStartTime(){return m_startTime;}

public :
	pid_t start();
	void stop();
};

/********************************
* ProcessTable
********************************/
class ProcessTable
{
private :
	vector<Process> m_processTable;
	typedef	struct 
	{
		char name[64];
		Process::ProcessStatus status;
	}SharedProcessTable;

	SharedProcessTable* m_sharedProcessTable;

public :
	ProcessTable();
	~ProcessTable();

public :
	void addEntry(Process varProc);
	void startAll();
	void stopAll();
	void initializeProcessTable(string file);

};

/* Event */
class TFW_Event : public TFW_Serializable
{
public :
	short kind;
	
public :
	virtual void serialize(TFW_Stream& buf) const;
	virtual void deserialize(TFW_Stream& buf);

public :
	TFW_Event();
	TFW_Event(int varID);
	~TFW_Event();
};

/* sub event define */
#define TFW_EVENT_DEFINE(ID_VAL, EVENT_NAME) \
	class EVENT_NAME : public TFW_Event  \
	{ \
	public : \
		enum{ID = ID_VAL }; \
		EVENT_NAME() : TFW_Event(ID){} \
	};

TFW_EVENT_DEFINE(ID_StartAllProcess, evStartAllProcess)
TFW_EVENT_DEFINE(ID_KillAllProcess, evKillAllProcess)
	
/* EventQueue */
class TFW_EventQueue
{
private:
	TFW_EventDispatcher* m_dispatcher;
	string m_mqId;
	mqd_t m_mFd;
	char* m_mqName;
	int m_msg_max_num;
	int m_msg_max_size;
	
public:
	/* callback ,function pointer */
	typedef void (*CallBackHandler)(TFW_Event* event);
	CallBackHandler handleEvent; /* for all child class */
	
public :
	/* registEventHandle */
	void registEventHandle(CallBackHandler handler){handleEvent = handler;}
	/* postEvent */
	void postEvent(TFW_Event* event);
	/* peek Event from mqueue, and fill the event with mqueue infomation */
	TFW_Event* peekEvent();
	/* create event object by event ID */
	TFW_Event* creatEvent(int id);
	/* initialize status */
	void initialize();
	/* open the mqueue */
	void start();
	/* get my descriptor */
	int getFd(){return m_mFd;}
	
public :
	/* constructor */
	TFW_EventQueue(string name, TFW_EventDispatcher* eventDispatcher, int max_msg_num, int max_size_mqueue);
	~TFW_EventQueue();
};

/// postEvent define
#define GEN(EVENT) postEvent(new EVENT)

/* EventDispatcher */
class TFW_EventDispatcher
{
private:
	vector<TFW_EventQueue*> m_eventqueueTable;
	int m_WalkupSelectPipe[2];
	int m_WalkupPipeForWrite;
	int m_WalkupPipeForRead;
	
public :
	void registEventQueue(TFW_EventQueue* eventqueue);
	void removeEventQueue(TFW_EventQueue* eventqueue);
	void initialize();
	/* stop */
	void stop();
	/* mainloop */
	void mainloop();
	
public :
	TFW_EventDispatcher();
	~TFW_EventDispatcher();
};

/* Stream */
class TFW_Stream
{
private :
	char* m_buf;
	int m_len;
	
public :
	TFW_Stream();
	~TFW_Stream();

public :
	/* temporary job */
	void setbuf(char* var);
	char* getbuf();
	int getlen();
};

/* common maroc */
#define max(X,Y) X>Y ? X : Y
